home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / apps / 197 / atari.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-20  |  13.1 KB  |  545 lines

  1. /*    ATARI.C:    Operating specific I/O and Spawning functions
  2.             for the ATARI ST operating system (GEMDOS)
  3.             for MicroEMACS 3.10
  4.             (C)opyright 1988 by Daniel M. Lawrence
  5. */
  6.  
  7. #include        <stdio.h>
  8. #include    "estruct.h"
  9. #include    "etype.h"
  10. #if    ATARI
  11. #include        "edef.h"
  12. #include    "elang.h"
  13. #include    "osbind.h"
  14. #include    "stat.h"    /* DMABUFFER is here */
  15. #include    "errno.h"
  16.  
  17. /****    ST Internals definitions        *****/
  18.  
  19. /*    BIOS calls */
  20.  
  21. #define    BCONSTAT    1    /* return input device status */
  22. #define    CONIN        2    /* read character from device */
  23. #define    BCONOUT        3    /* write character to device */
  24.  
  25. /*    XBIOS calls */
  26.  
  27. #define    INITMOUS    0    /* initialize the mouse */
  28. #define    GETREZ        4    /* get current resolution */
  29. #define    SETSCREEN    5    /* set screen resolution */
  30. #define    SETPALETTE    6    /* set the color pallette */
  31. #define    SETCOLOR    7    /* set or read a color */
  32. #define    CURSCONF    21    /* set cursor configuration */
  33. #define    IKBDWS        25    /* intelligent keyboard send command */
  34. #define    KBDVBASE    34    /* get keyboard table base */
  35.  
  36. /*    GEMDOS calls */
  37.  
  38. #define    EXEC        0x4b    /* Exec off a process */
  39.  
  40. #define    CON        2    /* CON: Keyboard and screen device */
  41.  
  42. /*
  43.  * This function is called once to set up the terminal device streams.
  44.  * On VMS, it translates TT until it finds the terminal, then assigns
  45.  * a channel to it and sets it raw. On CPM it is a no-op.
  46.  */
  47. ttopen()
  48. {
  49.     /* on all screens we are not sure of the initial position
  50.        of the cursor                    */
  51.     ttrow = 999;
  52.     ttcol = 999;
  53. }
  54.  
  55. /*
  56.  * This function gets called just before we go back home to the command
  57.  * interpreter. On VMS it puts the terminal back in a reasonable state.
  58.  * Another no-operation on CPM.
  59.  */
  60. ttclose()
  61. {
  62. }
  63.  
  64. /*
  65.  * Write a character to the display. On VMS, terminal output is buffered, and
  66.  * we just put the characters in the big array, after checking for overflow.
  67.  * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
  68.  * MS-DOS (use the very very raw console output routine).
  69.  */
  70. ttputc(c)
  71.  
  72. char c;
  73.  
  74. {
  75. }
  76.  
  77. /*
  78.  * Flush terminal buffer. Does real work where the terminal output is buffered
  79.  * up. A no-operation on systems where byte at a time terminal I/O is done.
  80.  */
  81. ttflush()
  82. {
  83. }
  84.  
  85. /*
  86.  * Read a character from the terminal, performing no editing and doing no echo
  87.  * at all. More complex in VMS that almost anyplace else, which figures. Very
  88.  * simple on CPM, because the system can do exactly what you want.
  89.  */
  90. ttgetc()
  91. {
  92. }
  93.  
  94. #if    TYPEAH
  95. typahead()
  96.  
  97. {
  98.     int rval;    /* return value from BIOS call */
  99.  
  100.     /* get the status of the console */
  101.     rval = bios(BCONSTAT, CON);
  102.  
  103.     /* end return the results */
  104.     if (rval == 0)
  105.         return(FALSE);
  106.     else
  107.         return(TRUE);
  108. }
  109. #endif
  110.  
  111. /*
  112.  * Create a subjob with a copy of the command intrepreter in it. When the
  113.  * command interpreter exits, mark the screen as garbage so that you do a full
  114.  * repaint. Bound to "^X C". Tuned to use any (tiny)shell in same directory. 
  115.  */
  116. spawncli(f, n)
  117. {
  118.     /* don't allow this command if restricted */
  119.     if (restflag)
  120.         return(resterr());
  121.  
  122.     mlerase();    /* clear the message line */
  123.         TTflush();
  124.     TTkclose();
  125.     system("shell.prg"); /* rename  jsh.prg  or   msh.prg  to  shell.prg; 
  126.                             and place with   emast.ttp   for generality */
  127.     TTkopen();
  128.         sgarbf = TRUE;
  129.         return(TRUE);
  130. }
  131.  
  132. /*
  133.  * Run a one-liner in a subjob. When the command returns, wait for a single
  134.  * character to be typed, then mark the screen as garbage so a full repaint is
  135.  * done. Bound to "C-X !".  Tuned for any "full-path-specified TOS program.
  136.  */
  137. spawn(f, n)
  138. {
  139.         register int    s;
  140.         char            line[NLINE];
  141.  
  142.     /* don't allow this command if restricted */
  143.     if (restflag)
  144.         return(resterr());
  145.  
  146.         if ((s=mlreply("!", line, NLINE)) != TRUE)
  147.                 return(s);
  148.     mlerase();
  149.     TTkclose();
  150.         system(line);
  151.     TTkopen();
  152.     /* if we are interactive, pause here */
  153.     if (clexec == FALSE) {
  154.             mlputs(TEXT6);
  155. /*                     "\r\n\n[End]" */
  156.             tgetc();
  157.         }
  158.         sgarbf = TRUE;
  159.         return (TRUE);
  160. }
  161.  
  162. /*
  163.  * Run an external program with arguments. When it returns, wait for a single
  164.  * character to be typed, then mark the screen as garbage so a full repaint is
  165.  * done. Bound to "C-X $".
  166.  */
  167.  
  168. execprg(f, n)
  169.  
  170. {
  171.         register int    s;
  172.         char            line[NLINE];
  173.  
  174.     /* don't allow this command if restricted */
  175.     if (restflag)
  176.         return(resterr());
  177.  
  178. #if     MWC
  179.         if ((s=mlreply("!", line, NLINE)) != TRUE)
  180.                 return(s);
  181.     mlerase();
  182.     TTkclose();
  183.         system(line);
  184.     TTkopen();
  185.     /* if we are interactive, pause here */
  186.     if (clexec == FALSE) {
  187.             mlputs(TEXT6);
  188. /*                     "\r\n\n[End]" */
  189.             tgetc();
  190.         }
  191.         sgarbf = TRUE;
  192.         return (TRUE);
  193. #endif
  194. }
  195.  
  196. /*
  197.  * Pipe a one line command into a window
  198.  * Bound to ^X @
  199.  */
  200. pipecmd(f, n)
  201. {
  202.         register int    s;    /* return status from CLI */
  203.     register WINDOW *wp;    /* pointer to new window */
  204.     register BUFFER *bp;    /* pointer to buffer to zot */
  205.         char    line[NLINE];    /* command line send to shell */
  206.     static char bname[] = "command";
  207.     FILE *fp;
  208.  
  209.     static char filnam[NSTRING] = "command";
  210.  
  211.     /* don't allow this command if restricted */
  212.     if (restflag)
  213.         return(resterr());
  214.  
  215.     /* get the command to pipe in */
  216.         if ((s=mlreply("@", line, NLINE)) != TRUE)
  217.                 return(s);
  218.  
  219.     /* get rid of the command output buffer if it exists */
  220.         if ((bp=bfind(bname, FALSE, 0)) != FALSE) {
  221.         /* try to make sure we are off screen */
  222.         wp = wheadp;
  223.         while (wp != NULL) {
  224.             if (wp->w_bufp == bp) {
  225.                 onlywind(FALSE, 1);
  226.                 break;
  227.             }
  228.             wp = wp->w_wndp;
  229.         }
  230.         if (zotbuf(bp) != TRUE)
  231.  
  232.             return(FALSE);
  233.     }
  234.  
  235. #if     MWC
  236.     strcat(line," >>");
  237.     strcat(line,filnam);
  238.     movecursor(term.t_nrow - 1, 0);
  239.     TTkclose();
  240.     system(line);
  241.     TTkopen();
  242.         sgarbf = TRUE;
  243.     if ((fp = fopen(filnam, "r")) == NULL) {
  244.         s = FALSE;
  245.     } else {
  246.         fclose(fp);
  247.         s = TRUE;
  248.     }
  249. #endif
  250.  
  251.     if (s != TRUE)
  252.         return(s);
  253.  
  254.     /* split the current window to make room for the command output */
  255.     if (splitwind(FALSE, 1) == FALSE)
  256.             return(FALSE);
  257.  
  258.     /* and read the stuff in */
  259.     if (getfile(filnam, FALSE) == FALSE)
  260.         return(FALSE);
  261.  
  262.     /* make this window in VIEW mode, update all mode lines */
  263.     curwp->w_bufp->b_mode |= MDVIEW;
  264.     wp = wheadp;
  265.     while (wp != NULL) {
  266.         wp->w_flag |= WFMODE;
  267.         wp = wp->w_wndp;
  268.     }
  269.  
  270.     /* and get rid of the temporary file */
  271.     unlink(filnam);
  272.     return(TRUE);
  273. }
  274.  
  275. /*
  276.  * filter a buffer through an external DOS program
  277.  * Bound to ^X #
  278.  */
  279. filter(f, n)
  280.  
  281. {
  282.         register int    s;    /* return status from CLI */
  283.     register BUFFER *bp;    /* pointer to buffer to zot */
  284.         char line[NLINE];    /* command line send to shell */
  285.     char tmpnam[NFILEN];    /* place to store real file name */
  286.     static char bname1[] = "fltinp";
  287.  
  288.     static char filnam1[] = "fltinp";
  289.     static char filnam2[] = "fltout";
  290.  
  291.     /* don't allow this command if restricted */
  292.     if (restflag)
  293.         return(resterr());
  294.  
  295.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  296.         return(rdonly());    /* we are in read only mode    */
  297.  
  298.     /* get the filter name and its args */
  299.         if ((s=mlreply("#", line, NLINE)) != TRUE)
  300.                 return(s);
  301.  
  302.     /* setup the proper file names */
  303.     bp = curbp;
  304.     strcpy(tmpnam, bp->b_fname);    /* save the original name */
  305.     strcpy(bp->b_fname, bname1);    /* set it to our new one */
  306.  
  307.     /* write it out, checking for errors */
  308.     if (writeout(filnam1) != TRUE) {
  309.         mlwrite(TEXT2);
  310. /*                      "[Cannot write filter file]" */
  311.         strcpy(bp->b_fname, tmpnam);
  312.         return(FALSE);
  313.     }
  314.  
  315. #if     MWC
  316.     strcat(line," <fltinp >fltout");
  317.     movecursor(term.t_nrow - 1, 0);
  318.     TTkclose();
  319.     system(line);
  320.     TTkopen();
  321.         sgarbf = TRUE;
  322.     s = TRUE;
  323. #endif
  324.  
  325.     /* on failure, escape gracefully */
  326.     if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) {
  327.         mlwrite(TEXT3);
  328. /*                      "[Execution failed]" */
  329.         strcpy(bp->b_fname, tmpnam);
  330.         unlink(filnam1);
  331.         unlink(filnam2);
  332.         return(s);
  333.     }
  334.  
  335.     /* reset file name */
  336.     strcpy(bp->b_fname, tmpnam);    /* restore name */
  337.     bp->b_flag |= BFCHG;        /* flag it as changed */
  338.  
  339.     /* and get rid of the temporary file */
  340.     unlink(filnam1);
  341.     unlink(filnam2);
  342.     return(TRUE);
  343. }
  344.  
  345. rename(oldname, newname)    /* rename a file */
  346.  
  347. char *oldname;        /* original file name */
  348. char *newname;        /* new file name */
  349.  
  350. {
  351.     Frename(0, oldname, newname);
  352. }
  353.  
  354. /* return a system dependant string with the current time */
  355.  
  356. char *PASCAL NEAR timeset()
  357.  
  358. {
  359.     register char *sp;    /* temp string pointer */
  360.     char buf[16];        /* time data buffer */
  361.  
  362.     time(buf);
  363.     sp = ctime(buf);
  364.     sp[strlen(sp)-1] = 0;
  365.     return(sp);
  366. }
  367.  
  368. /*    extcode:    resolve MSDOS extended character codes
  369.             encoding the proper sequences into emacs
  370.             printable character specifications
  371.  
  372.             Well, yes... The ATARI ST was supposed to be
  373.             a PC clone originally... These codes are the
  374.             same for the ST.
  375. */
  376.  
  377. int extcode(c)
  378.  
  379. unsigned c;    /* byte following a zero extended char byte */
  380.  
  381. {
  382.     /* function keys 1 through 9 */
  383.     if (c >= 59 && c < 68)
  384.         return(SPEC | c - 58 + '0');
  385.  
  386.     /* function key 10 */
  387.     if (c == 68)
  388.         return(SPEC | '0');
  389.  
  390.     /* shifted function keys */
  391.     if (c >= 84 && c < 93)
  392.         return(SPEC | SHFT | c - 83 + '0');
  393.     if (c == 93)
  394.         return(SPEC | SHFT | '0');
  395.  
  396.     /* control function keys */
  397.     if (c >= 94 && c < 103)
  398.         return(SPEC | CTRL | c - 93 + '0');
  399.     if (c == 103)
  400.         return(SPEC | CTRL | '0');
  401.  
  402.     /* ALTed function keys */
  403.     if (c >= 104 && c < 113)
  404.         return(SPEC | ALTD | c - 103 + '0');
  405.     if (c == 113)
  406.         return(SPEC | ALTD | '0');
  407.  
  408.     /* ALTed number keys */
  409.     if (c >= 120 && c < 129)
  410.         return(ALTD | c - 119 + '0');
  411.     if (c == 130)
  412.         return(ALTD | '0');
  413.  
  414.     /* some others as well */
  415.     switch (c) {
  416.         case 3:        return(0);        /* null */
  417.         case 15:    return(SHFT | CTRL | 'I');    /* backtab */
  418.  
  419.         case 16:    return(ALTD | 'Q');
  420.         case 17:    return(ALTD | 'W');
  421.         case 18:    return(ALTD | 'E');
  422.         case 19:    return(ALTD | 'R');
  423.         case 20:    return(ALTD | 'T');
  424.         case 21:    return(ALTD | 'Y');
  425.         case 22:    return(ALTD | 'U');
  426.         case 23:    return(ALTD | 'I');
  427.         case 24:    return(ALTD | 'O');
  428.         case 25:    return(ALTD | 'P');
  429.  
  430.         case 30:    return(ALTD | 'A');
  431.         case 31:    return(ALTD | 'S');
  432.         case 32:    return(ALTD | 'D');
  433.         case 33:    return(ALTD | 'F');
  434.         case 34:    return(ALTD | 'G');
  435.         case 35:    return(ALTD | 'H');
  436.         case 36:    return(ALTD | 'J');
  437.         case 37:    return(ALTD | 'K');
  438.         case 38:    return(ALTD | 'L');
  439.  
  440.         case 44:    return(ALTD | 'Z');
  441.         case 45:    return(ALTD | 'X');
  442.         case 46:    return(ALTD | 'C');
  443.         case 47:    return(ALTD | 'V');
  444.         case 48:    return(ALTD | 'B');
  445.         case 49:    return(ALTD | 'N');
  446.         case 50:    return(ALTD | 'M');
  447.  
  448.         case 71:    return(SPEC | '<');    /* HOME */
  449.         case 72:    return(SPEC | 'P');    /* cursor up */
  450.         case 73:    return(SPEC | 'Z');    /* page up */
  451.         case 75:    return(SPEC | 'B');    /* cursor left */
  452.         case 77:    return(SPEC | 'F');    /* cursor right */
  453.         case 79:    return(SPEC | '>');    /* end */
  454.         case 80:    return(SPEC | 'N');    /* cursor down */
  455.         case 81:    return(SPEC | 'V');    /* page down */
  456.         case 82:    return(SPEC | 'C');    /* insert */
  457.         case 83:    return(SPEC | 'D');    /* delete */
  458.         case 115:    return(SPEC | CTRL | 'B');    /* control left */
  459.         case 116:    return(SPEC | CTRL | 'F');    /* control right */
  460.         case 117:    return(SPEC | CTRL | '>');    /* control END */
  461.         case 118:    return(SPEC | CTRL | 'V');    /* control page down */
  462.         case 119:    return(SPEC | CTRL | '<');    /* control HOME */
  463.         case 132:    return(SPEC | CTRL | 'Z');    /* control page up */
  464.     }
  465.  
  466.     return(ALTD | c);
  467. }
  468.  
  469. /*    FILE Directory routines        */
  470.  
  471. static DMABUFFER info;        /* Info about the file */
  472. char path[NFILEN];        /* path of file to find */
  473. char rbuf[NFILEN];        /* return file buffer */
  474.  
  475. /*    do a wild card directory search (for file name completion) */
  476.  
  477. char *PASCAL NEAR getffile(fspec)
  478.  
  479. char *fspec;    /* file to match */
  480.  
  481. {
  482.     register int index;        /* index into various strings */
  483.     register int point;        /* index into other strings */
  484.     register int extflag;        /* does the file have an extention? */
  485.     char fname[NFILEN];        /* file/path for TOS call */
  486.  
  487.     /* first parse the file path off the file spec */
  488.     strcpy(path, fspec);
  489.     index = strlen(path) - 1;
  490.     while (index >= 0 && (path[index] != '/' &&
  491.                 path[index] != '\\' && path[index] != ':'))
  492.         --index;
  493.     path[index+1] = 0;
  494.  
  495.     /* check for an extension */
  496.     point = strlen(fspec) - 1;
  497.     extflag = FALSE;
  498.     while (point >= 0) {
  499.         if (fspec[point] == '.') {
  500.             extflag = TRUE;
  501.             break;
  502.         }
  503.         point--;
  504.     }
  505.  
  506.     /* construct the composite wild card spec */
  507.     strcpy(fname, path);
  508.     strcat(fname, &fspec[index+1]);
  509.     strcat(fname, "*");
  510.     if (extflag == FALSE)
  511.         strcat(fname, ".*");
  512.  
  513.     /* and call for the first file */
  514.  
  515.     Fsetdta(&info);        /* Initialize buffer for our search */
  516.     if (Fsfirst(fname, 0xF7) != AE_OK)
  517.         return(NULL);
  518.  
  519.     /* return the first file name! */
  520.     strcpy(rbuf, path);
  521.     strcat(rbuf, info.d_fname);
  522.     mklower(rbuf);
  523.     return(rbuf);
  524. }
  525.  
  526. char *PASCAL NEAR getnfile()
  527.  
  528. {
  529.  
  530.     /* and call for the first file */
  531.     if (Fsnext() != AE_OK)
  532.         return(NULL);
  533.  
  534.     /* return the first file name! */
  535.     strcpy(rbuf, path);
  536.     strcat(rbuf, info.d_fname);
  537.     mklower(rbuf);
  538.     return(rbuf);
  539. }
  540. #else
  541. atarihello()
  542. {
  543. }
  544. #endif
  545.